package checkLicense

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/robfig/cron/v3"
	"io"
	"os"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/atotto/clipboard"
	"github.com/denisbrodbeck/machineid"
	"github.com/ncruces/zenity"
)

type AppLicenseInfos struct {
	AppName        string //应用名称
	AppCompany     string //应用发布的公司
	AppUUID        string //此次发布应用的UUID
	ObjUUID        string //目标设备的UUID
	AuthorizedName string //授权名称
	AuthorizedTime string //授权时间
	LimitedTime    string //到期日期
}

var Key = "kesselkesselkits"

func CheckLicense() {
	//判断首次启动文件是否存在
	ok, _, err := Check()
	if !ok && err != nil {
		os.Exit(0)
		return
	}
}

func Check() (bool, AppLicenseInfos, error) {
	lic, err, licenseData := ValidAppLic("license.lic", Key)
	if err != nil {
		if strings.Contains(err.Error(), "失败") || strings.Contains(err.Error(), "不存在") {
			//打开注册表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
			//找到名为 "MachineGuid" 的密钥，此密钥在Windows安装过程中唯一生成
			//无论是否进行任何硬件交换，它都不会更改（除了更换安装了操作系统的可启动硬盘驱动器）
			id, getIdErr := machineid.ID()
			errStr := err.Error() + "\n当前设备ID：" + id
			if getIdErr != nil {
				errStr += "\n获取本机ID失败：" + getIdErr.Error()
			}
			errStr += "\n如果您已购买授权，请将以上设备ID发送给厂家进行处理！(设备ID已复制到剪切板)"

			switch thisOs := runtime.GOOS; thisOs {
			case "linux":
				fmt.Println(errStr)
			case "darwin":
				fmt.Println(errStr)
			case "windows":
				clipboard.WriteAll(id) // 复制设备ID到剪切板
				zenity.Error(errStr + "(设备ID已复制到剪切板)")
			default:
				fmt.Println(errStr)
			}
		} else {
			switch thisOs := runtime.GOOS; thisOs {
			case "linux":
				fmt.Println(err)
			case "darwin":
				fmt.Println(err)
			case "windows":
				zenity.Error(err.Error())
			default:
				fmt.Println(err)
			}
		}

	}

	return lic, licenseData, err
}

func ValidAppLic(appInfoFile, key string) (res bool, err error, license AppLicenseInfos) {
	var licenseData AppLicenseInfos
	file, err := os.OpenFile(appInfoFile, os.O_RDONLY, 0777)
	if err != nil {
		return false, errors.New("授权文件不存在"), licenseData
	}
	defer file.Close()
	contentByte, err := io.ReadAll(file)
	if err != nil {
		return false, errors.New("授权文件读取失败"), licenseData
	}
	tmpText := string(contentByte)
	//进行解密
	tmpText = AesDecrypt(tmpText, key)
	err = json.Unmarshal([]byte(tmpText), &licenseData)
	conf := AppLicenseInfos{}
	if err := json.Unmarshal([]byte(tmpText), &conf); err == nil {
		//获取本机的ID
		id, err := machineid.ID()
		if err != nil {
			return false, errors.New("获取本机ID失败"), licenseData
		}
		if conf.ObjUUID != id {
			return false, errors.New("授权文件不适用于此设备或未授权，本机ID为:" + id), licenseData
		}

		AuthorizedTime, _ := time.ParseInLocation("2006-01-02 15:04:05", conf.AuthorizedTime, time.Local)
		subTime := AuthorizedTime.Sub(time.Now()).Minutes()
		if subTime > 0 {
			return false, errors.New("设备时间出错！请检查后重启程序"), licenseData
		}
		limitedTime := conf.LimitedTime
		if limitedTime != "" {
			licDate, _ := strconv.Atoi(limitedTime)
			nowDate := time.Now().Format("20060102")
			currentDate, _ := strconv.Atoi(nowDate)
			if licDate < currentDate {
				errInfo := fmt.Sprintf("授权文件已过期!授权结束日期:%d", licDate)
				return false, errors.New(errInfo), licenseData
			}
		}

	}
	return true, nil, licenseData
}

// LoopDetection 循环检测授权
func LoopDetection() {
	job := cron.New()
	job.AddFunc("@every 1h", func() {
		CheckLicense()
	})
	job.Start()
}
